/*
 * Copyright (c) 2021 Huawei Device Co.,  Ltd.
 * Licensed under the Apache License,  Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,  software
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,  either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "recptprinter_srv_proxy.h"
#include <string.h>
#include <ipc_types.h>
#include <message_option.h>
#include <message_parcel.h>

#include "recptprinter_hilog.h"
#include "recptprinter_errors.h"
#include "recptprinter_common.h"

namespace SwanLink {
namespace Finance {

int RecptprinterSrvProxy::GetPrintFormat(int handle, PrintFormatType ftt)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(RecptprinterSrvProxy::GetDescriptor())) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, ftt, -1);
    
    int ret = remote->SendRequest(static_cast<int>(IRecptprinterSrv::RECPTPRINTER_GETPRINTFORMAT),  data,  reply,  option);

    if (ret != ERR_OK) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

void RecptprinterSrvProxy::SetPrintFormat(int handle, PrintFormatType ftt, int value)
{
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(RecptprinterSrvProxy::GetDescriptor())) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "Write descriptor failed");
        return;
    }
    
    WRITE_PARCEL_NO_RET(data, Int32, handle);
    WRITE_PARCEL_NO_RET(data, Int32, ftt);
    WRITE_PARCEL_NO_RET(data, Int32, value);
    
    int ret = remote->SendRequest(static_cast<int>(IRecptprinterSrv::RECPTPRINTER_SETPRINTFORMAT),
        data,  reply,  option);

    if (ret != ERR_OK) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return;
    }
    // READ_PARCEL_WITH_RET(reply, , result, );

    return;
}

void RecptprinterSrvProxy::GetDeviceSpec(int handle, DeviceSpec &spec)
{
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(RecptprinterSrvProxy::GetDescriptor())) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "Write descriptor failed");
        return;
    }
    WRITE_PARCEL_NO_RET(data, Int32, handle);
    
    int ret = remote->SendRequest(static_cast<int>(IRecptprinterSrv::RECPTPRINTER_GETDEVICESPEC),
        data,  reply,  option);

    if (ret != ERR_OK) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return;
    }

    READ_BUFFER_WITH_COPY(data, DeviceSpec, &spec, sizeof(spec));
    return;
}

int RecptprinterSrvProxy::FeedPaper(int handle, int line)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(RecptprinterSrvProxy::GetDescriptor())) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, line, -1);
    
    int ret = remote->SendRequest(static_cast<int>(IRecptprinterSrv::RECPTPRINTER_FEEDPAPER),  data,  reply,  option);

    if (ret != ERR_OK) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int RecptprinterSrvProxy::CutPaper(int handle, int line, int mode)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(RecptprinterSrvProxy::GetDescriptor())) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, line, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, mode, -1);
    
    int ret = remote->SendRequest(static_cast<int>(IRecptprinterSrv::RECPTPRINTER_CUTPAPER),  data,  reply,  option);

    if (ret != ERR_OK) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int RecptprinterSrvProxy::AddText(int handle, int x, int y, const std::string& text)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(RecptprinterSrvProxy::GetDescriptor())) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, x, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, y, -1);
    WRITE_PARCEL_WITH_RET(data, String, text, -1);
    
    int ret = remote->SendRequest(static_cast<int>(IRecptprinterSrv::RECPTPRINTER_ADDTEXT),  data,  reply,  option);

    if (ret != ERR_OK) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int RecptprinterSrvProxy::AddBitmap(int handle, int x, int y, const std::string& lpath)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(RecptprinterSrvProxy::GetDescriptor())) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, x, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, y, -1);
    WRITE_PARCEL_WITH_RET(data, String, lpath, -1);
    
    int ret = remote->SendRequest(static_cast<int>(IRecptprinterSrv::RECPTPRINTER_ADDBITMAP),  data,  reply,  option);

    if (ret != ERR_OK) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int RecptprinterSrvProxy::AddQRCode(int handle, int x, int y, int w, const std::string& qr)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(RecptprinterSrvProxy::GetDescriptor())) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, x, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, y, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, w, -1);
    WRITE_PARCEL_WITH_RET(data, String, qr, -1);
    
    int ret = remote->SendRequest(static_cast<int>(IRecptprinterSrv::RECPTPRINTER_ADDQRCODE),  data,  reply,  option);

    if (ret != ERR_OK) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

int RecptprinterSrvProxy::AddBarCode(int handle, int x, int y, BarCodeSpec &spec, const std::string& bar)
{
    int result = -1;
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return result;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    
    if (!data.WriteInterfaceToken(RecptprinterSrvProxy::GetDescriptor())) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "Write descriptor failed");
        return result;
    }
    
    WRITE_PARCEL_WITH_RET(data, Int32, handle, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, x, -1);
    WRITE_PARCEL_WITH_RET(data, Int32, y, -1);
    WRITE_BUFFER_WITH_RET(data, Buffer, &spec, sizeof(spec), -1);
    WRITE_PARCEL_WITH_RET(data, String, bar, -1);
    
    int ret = remote->SendRequest(static_cast<int>(IRecptprinterSrv::RECPTPRINTER_ADDBARCODE),  data,  reply,  option);

    if (ret != ERR_OK) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "SendRequest is failed,  ret: %d",  ret);
        return result;
    }
    READ_PARCEL_WITH_RET(reply, Int32, result, -1);

    return result;
}

void RecptprinterSrvProxy::StartPrint(int handle, int timeout, PrintListener *listener)
{
    sptr<IRemoteObject> remote = Remote();
    if (remote == nullptr) return;
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;

    // 使用异步
    option.SetFlags(MessageOption::TF_ASYNC);
    
    if (!data.WriteInterfaceToken(RecptprinterSrvProxy::GetDescriptor())) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "Write descriptor failed");
        return;
    }
    
    WRITE_PARCEL_NO_RET(data, Int32, handle);
    WRITE_PARCEL_NO_RET(data, Int32, timeout);
    IRecptprinterObserver *remote_object = static_cast<IRecptprinterObserver*>(listener);
    if (remote_object) {
        if (!data.WriteRemoteObject(remote_object->AsObject())) {
            RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "WriteRemoteObject is failed");
            return;
        }
    }

    int ret = remote->SendRequest(static_cast<int>(IRecptprinterSrv::RECPTPRINTER_STARTPRINT),  data,  reply,  option);

    if (ret != ERR_OK) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "SendRequest is failed,  ret: %{public}d",  ret);
        return;
    }
    return;
}
}  // namespace Finance
}  // namespace SwanLink
